package com.playcrab.adouban;

import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.app.Activity;

abstract public class AutoRefreshAdapter<T> extends ArrayAdapter<T> {

	Activity context;
	LayoutInflater inflater;
	List<T> itemList;

	abstract protected boolean cacheInBackground();
	abstract protected void appendCachedData();
	abstract protected View getItemView(int position);
	private View pendingView=null;
	private int pendingPosition=-1;
	private AtomicBoolean keepOnAppending=new AtomicBoolean(true);
	private RotateAnimation rotate=null;

	public AutoRefreshAdapter(Activity context, List<T> itemList) {
		super(context, R.layout.autorefresh_row, itemList);
		inflater = LayoutInflater.from(context);

		this.context = context;
		this.itemList = itemList;
		// TODO Auto-generated constructor stub
		
		rotate=new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF,
				0.5f, Animation.RELATIVE_TO_SELF,
				0.5f);
		rotate.setDuration(600);
		rotate.setRepeatMode(Animation.RESTART);
		rotate.setRepeatCount(Animation.INFINITE);
	}
	
	@Override
	public int getCount() { 
		if (keepOnAppending.get()) {
			return(itemList.size()+1);		// one more for "pending"
		}
		
		return(itemList.size());
	}
	
	
	
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		if (position == itemList.size() &&
				keepOnAppending.get()) {
			
			if (pendingView==null) {
				pendingView=getPendingView(parent);
				pendingPosition=position;
				
				new AppendTask().execute();
			}
			
			return(pendingView);
		}
		
		System.out.println(itemList.size());
		View row = convertView;
		row = inflater.inflate(R.layout.autorefresh_row, null);
		row.setLongClickable(true);
		row.setClickable(true);
		FrameLayout flayout = (FrameLayout) row.findViewById(R.id.autofresh);
		flayout.addView(getItemView(position), 
				new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
		
		return row;

	}
	
   @Override
    public boolean areAllItemsEnabled() {
        return true;
    }

    @Override
    public boolean isEnabled(int position) {
        return true;
    }

	public void addSubjects(List<T> moreItemList) {
		// TODO Auto-generated method stub
		if (moreItemList.size() != 0) {
			itemList.addAll(itemList.size(), moreItemList);
			notifyDataSetChanged();
		}
	}
	
	class AppendTask extends AsyncTask<Void, Void, Void> {
		@Override
		protected Void doInBackground(Void... params) {
			keepOnAppending.set(cacheInBackground());
			
			return(null);
		}
		
		@Override
		protected void onPostExecute(Void unused) {
			appendCachedData();
			rebindPendingView(pendingPosition, pendingView);
			pendingView=null;
			pendingPosition=-1;
		}
	}
	
	protected View getPendingView(ViewGroup parent) {
		View row=inflater.inflate(R.layout.autorefresh_row, null);		
		View child=row.findViewById(R.id.throbber);
		child.setVisibility(View.VISIBLE);
		child.startAnimation(rotate);
		
		return(row);
	}
	
	protected void rebindPendingView(int position, View row) {
		View child=row.findViewById(R.id.throbber);
		child.setVisibility(View.GONE);
		child.clearAnimation();
	}
	
}